/*
 * Copyright 2011-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sabayframework.activity.impl;

import org.sabayframework.activity.ActivityContext;
import org.sabayframework.channel.Lock;



/**
 * Composition of several activities that are called for each input object 
 * one after another in the same thread. 
 * 
 * @author Alex Antonau
 * */
public class Sequence<I, O> extends StatefulActivity<I, O> {
	
	protected StatefulActivity<I, O>[] activities;
	
	public Sequence() {
		super();
	}
	/**
	* Constructor accepts activities that will be executed in sequence
	* @SafeVarargs
	*/ 
	public Sequence(StatefulActivity<I, O>...activities) {
		if(activities == null || activities.length == 0) throw new IllegalArgumentException();
		this.activities = activities;
	}

	public StatefulActivity<I, O>[] getActivities() {
		return activities;
	}

	public void setFunctions(StatefulActivity<I, O>[] activities) {
		this.activities = activities;
	}

	@Override
	public void beforeExecute(ActivityContext<I, O> ctx) throws Exception {
		super.beforeExecute(ctx);
		for(StatefulActivity<I, O> a : activities) a.beforeExecute(ctx);
	}

	@Override
	public void afterExecute(ActivityContext<I, O> ctx) throws Exception {
		for(StatefulActivity<I, O> a : activities) a.afterExecute(ctx);
		super.afterExecute(ctx);
	}

	@Override
	public void input(ActivityContext<I, O> ctx, Lock<I> inputLock) throws Exception {
		for(StatefulActivity<I, O> p : activities) p.input(ctx, inputLock);
	}

	@Override
	public void execute(ActivityContext<I, O> ctx) throws Exception {
		for(StatefulActivity<I, O> p : activities) p.execute(ctx);
	}
	
	@Override
	public void output(ActivityContext<I, O> ctx, Lock<O> outputLock) throws Exception {
		for(StatefulActivity<I, O> p : activities) p.output(ctx, outputLock);
		
	}

	@Override
	public int getOutputSize(ActivityContext<I, O> ctx) {
		return activities[activities.length-1].getOutputSize(ctx);
	}

	@Override
	public int getInputSize(ActivityContext<I, O> ctx) {
		return activities[0].getInputSize(ctx);
	}

}
